package com.xhwl.data.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xhwl.common.dto.cent.sdata.SpaceFunctionTypeDTO;
import com.xhwl.common.enums.OrganizationTypeEnum;
import com.xhwl.common.pojo.ResultJson;
import com.xhwl.common.pojo.cent.sdata.*;
import com.xhwl.common.query.cent.sdata.SpaceFunctionTypeQuery;
import com.xhwl.data.dao.SpaceFunctionTypeDao;
import com.xhwl.data.service.*;
import com.xhwl.data.util.AutoCodeUtils;
import com.xhwl.data.util.CodePrefixConstant;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author yf
 * @Description:
 * @Date Create in 10:32 2022/06/07
 */
@Service
public class SpaceFunctionTypeServiceImpl extends ServiceImpl<SpaceFunctionTypeDao, SpaceFunctionType> implements ISpaceFunctionTypeService {
    @Autowired
    private SpaceFunctionTypeDao spaceFunctionTypeDao;

    @Autowired
    private IBuildingService buildingService;

    @Autowired
    private IFloorService floorService;

    @Autowired
    private IRoomService roomService;

    @Autowired
    private IPublicAreaService publicAreaService;

    @Override
    public ResultJson create(SpaceFunctionTypeDTO spaceFunctionTypeDTO) {
        if (0 != spaceFunctionTypeDao.checkUniqueName(spaceFunctionTypeDTO)) {
            return ResultJson.fail("名称重复");
        }
        Integer parentId = spaceFunctionTypeDTO.getParentId();
        if (0 == parentId) {
            spaceFunctionTypeDTO.setLevel(1);
        } else {
            SpaceFunctionType spaceFunctionType = spaceFunctionTypeDao.selectById(parentId);
            if (null == spaceFunctionType) {
                return ResultJson.fail("父级不存在");
            }
            Integer level = spaceFunctionType.getLevel() + 1;
            if (level > 3) {
                return ResultJson.fail("层级不能超过3级");
            }
            spaceFunctionTypeDTO.setLevel(level);
        }
        spaceFunctionTypeDao.insert(spaceFunctionTypeDTO);
        Integer id = spaceFunctionTypeDTO.getId();
        String code = AutoCodeUtils.codeFormat(CodePrefixConstant.SPACE_FUNCTION_TYPE_PREFIX, id, CodePrefixConstant.CODE_LENGTH);
        int result = spaceFunctionTypeDao.update(null, new UpdateWrapper<SpaceFunctionType>()
                .set("code", code).eq("id", id));
        return result == 1 ? ResultJson.success("操作成功") : ResultJson.fail("操作失败");
    }

    @Override
    public ResultJson update(SpaceFunctionTypeDTO spaceFunctionTypeDTO) {
        if (0 != spaceFunctionTypeDao.checkUniqueName(spaceFunctionTypeDTO)) {
            return ResultJson.fail("名称重复");
        }
        int update = spaceFunctionTypeDao.update(null, new UpdateWrapper<SpaceFunctionType>()
                .set("name", spaceFunctionTypeDTO.getName())
                .eq("id", spaceFunctionTypeDTO.getId())
                .gt("level", 0));
        return update == 1 ? ResultJson.success("操作成功") : ResultJson.fail("操作失败");
    }


    @Override
    public ResultJson delete(Integer id) {
        SpaceFunctionType spaceFunctionType = spaceFunctionTypeDao.selectById(id);
        if (null == spaceFunctionType) {
            return ResultJson.fail("操作失败");
        }
        int num = spaceFunctionTypeDao.selectCount(new QueryWrapper<SpaceFunctionType>()
                .eq("parent_id", id));
        if (num > 0) {
            return ResultJson.fail("存在子类型数据");
        }
        int delete = spaceFunctionTypeDao.delete(new QueryWrapper<SpaceFunctionType>()
                .eq("id", id)
                .gt("level", 0));
        return delete == 1 ? ResultJson.success("操作成功") : ResultJson.fail("操作失败");
    }

    @Override
    public Page<SpaceFunctionTypeDTO> page(SpaceFunctionTypeQuery query) {
        Integer enterpriseId = query.getEnterpriseId();
        Short industryId = query.getIndustryId();
        Integer orgType = query.getOrgType();
        Integer size = query.getSize();
        Integer current = query.getCurrent();
        Page<SpaceFunctionTypeDTO> spaceFunctionTypeDTOPage = new Page<>(current, size);
        Page<SpaceFunctionType> spaceFunctionTypePage = spaceFunctionTypeDao
                .selectPage(new Page<>(current, size),
                        new QueryWrapper<SpaceFunctionType>()
                                .eq("org_type", orgType)
                                .eq("level", 1)
                                .and(x -> x.eq("enterprise_id", enterpriseId)
                                        .or().like(null != industryId, "industry_id", industryId))
                );
        long total = spaceFunctionTypePage.getTotal();
        long pages = spaceFunctionTypePage.getPages();
        spaceFunctionTypeDTOPage.setTotal(total);
        spaceFunctionTypeDTOPage.setPages(pages);
        List<SpaceFunctionType> records = spaceFunctionTypePage.getRecords();
        if (0 == total) {
            return spaceFunctionTypeDTOPage;
        }
        List<SpaceFunctionType> allLevelList = spaceFunctionTypeDao.selectList(new QueryWrapper<SpaceFunctionType>()
                .eq("org_type", orgType)
                .ge("level", 1)
                .and(x -> x.eq("enterprise_id", enterpriseId)
                        .or().like(null != industryId, "industry_id", industryId))
        );
        List<Integer> ids = records.stream().map(x -> x.getId()).collect(Collectors.toList());
        List<SpaceFunctionTypeDTO> spaceFunctionTypeDTOS = processBean(allLevelList).stream()
                .filter(x -> ids.contains(x.getId())).collect(Collectors.toList());
        spaceFunctionTypeDTOPage.setRecords(spaceFunctionTypeDTOS);
        return spaceFunctionTypeDTOPage;
    }

    @Override
    public List<SpaceFunctionTypeDTO> list(SpaceFunctionTypeQuery query) {
        Short industryId = query.getIndustryId();
        List<SpaceFunctionType> spaceFunctionTypes = spaceFunctionTypeDao.selectList(new QueryWrapper<SpaceFunctionType>()
                .eq("org_type", query.getOrgType())
                .ge("level", 1)
                .and(x -> x.eq("enterprise_id", query.getEnterpriseId())
                        .or().like(null != industryId, "industry_id", industryId)));
        if (spaceFunctionTypes.size() > 0) {
            List<SpaceFunctionTypeDTO> spaceFunctionTypeDTOS = processBean(spaceFunctionTypes);
            return spaceFunctionTypeDTOS;
        }
        return null;
    }

    private SpaceFunctionTypeDTO processBean(SpaceFunctionType spaceFunctionType) {
        SpaceFunctionTypeDTO spaceFunctionTypeDTO = new SpaceFunctionTypeDTO();
        BeanUtils.copyProperties(spaceFunctionType, spaceFunctionTypeDTO);
        List<SpaceFunctionTypeDTO> spaceFunctionTypeDTOS = new ArrayList<>();
        spaceFunctionTypeDTO.setChildren(spaceFunctionTypeDTOS);
        return spaceFunctionTypeDTO;
    }

    private List<SpaceFunctionTypeDTO> processBean(List<SpaceFunctionType> spaceFunctionTypes) {
        List<SpaceFunctionTypeDTO> spaceFunctionTypeDTOS = spaceFunctionTypes.stream().map(this::processBean).collect(Collectors.toList());
        int maxLevel = spaceFunctionTypeDTOS.stream().map(SpaceFunctionType::getLevel).max(Integer::compare).get();
        if (1 == maxLevel) {
            return spaceFunctionTypeDTOS;
        }
        for (int i = maxLevel; i > 1; i--) {
            for (SpaceFunctionTypeDTO child : spaceFunctionTypeDTOS) {
                if (i == child.getLevel()) {
                    for (SpaceFunctionTypeDTO parent : spaceFunctionTypeDTOS) {
                        if (parent.getId().equals(child.getParentId())) {
                            List<SpaceFunctionTypeDTO> children = parent.getChildren();
                            children.add(child);
                            parent.setChildren(children);
                        }
                    }
                }
            }
        }
        List<SpaceFunctionTypeDTO> result = spaceFunctionTypeDTOS.stream()
                .filter(x -> x.getLevel() == 1).collect(Collectors.toList());
        return result;
    }
}
